package com.mindskip.xzs.service.impl;

import com.mindskip.xzs.context.WebContext;
import com.mindskip.xzs.domain.dto.admin.task.TaskItemObject;
import com.mindskip.xzs.domain.dto.student.task.TaskItemAnswerObject;
import com.mindskip.xzs.domain.entity.*;
import com.mindskip.xzs.domain.enums.ExamPaperTypeEnum;
import com.mindskip.xzs.domain.vo.student.dashboard.*;
import com.mindskip.xzs.service.*;
import com.mindskip.xzs.utility.BeanCopyUtils;
import com.mindskip.xzs.utility.DateTimeUtil;
import com.mindskip.xzs.utility.JsonUtil;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

@Service
public class DashboardServiceImpl implements DashboardService {

    private final WebContext webContext;

    private final ExamPaperService examPaperService;

    private final TaskExamService taskExamService;

    private final ExamPaperAnswerService examPaperAnswerService;

    private final TaskExamCustomerAnswerService taskExamCustomerAnswerService;

    private final TextContentService textContentService;

    public DashboardServiceImpl(WebContext webContext, ExamPaperService examPaperService, TaskExamService taskExamService, ExamPaperAnswerService examPaperAnswerService, TaskExamCustomerAnswerService taskExamCustomerAnswerService, TextContentService textContentService) {
        this.webContext = webContext;
        this.examPaperService = examPaperService;
        this.taskExamService = taskExamService;
        this.examPaperAnswerService = examPaperAnswerService;
        this.taskExamCustomerAnswerService = taskExamCustomerAnswerService;
        this.textContentService = textContentService;
    }

    @Override
    public IndexVO index() {

        IndexVO indexVO = new IndexVO();
        User user = webContext.getCurrentUser();

        // 得到固定试卷信息
        PaperFilter fixedPaperFilter = new PaperFilter();
        fixedPaperFilter.setGradeLevel(user.getUserLevel());
        fixedPaperFilter.setExamPaperType(ExamPaperTypeEnum.Fixed.getCode());
        indexVO.setFixedPaper(examPaperService.indexFixedPaper(fixedPaperFilter));

        // 得到时段试卷信息
        PaperFilter timeLimitPaperFilter = new PaperFilter();
        timeLimitPaperFilter.setDateTime(new Date());
        timeLimitPaperFilter.setGradeLevel(user.getUserLevel());
        timeLimitPaperFilter.setExamPaperType(ExamPaperTypeEnum.TimeLimit.getCode());
        List<TimeLimitPaper> oldTimeLimitPaperList = examPaperService.indexTimeLimitPaper(timeLimitPaperFilter);
        List<TimeLimitPaper> newTimeLimitPaperList = oldTimeLimitPaperList.stream()
                        .peek(timeLimitPaper -> {
                            timeLimitPaper.setStartTime(DateTimeUtil.dateFormat(timeLimitPaper.getLimitStartTime()));
                            timeLimitPaper.setEndTime(DateTimeUtil.dateFormat(timeLimitPaper.getLimitEndTime()));
                        })
                        .collect(Collectors.toList());
        indexVO.setTimeLimitPaper(newTimeLimitPaperList);

        return indexVO;

    }

    public List<TaskItemVO> task() {

        List<TaskExam> taskExamList = taskExamService.getTaskExamByGradeLevel(webContext.getCurrentUser().getUserLevel());

        // 给 List<TaskItemVO> 中每个 TaskItemVO 元素中的 id、title 赋值
        List<TaskItemVO> taskItemVOList = BeanCopyUtils.copyBeanList(taskExamList, TaskItemVO.class);

        List<Integer> taskExamIds = taskItemVOList.stream()
                        .map(TaskItemVO::getId)
                        .collect(Collectors.toList());

        List<TaskExamCustomerAnswer> taskExamCustomerAnswerList = taskExamCustomerAnswerService.getTaskExamCustomerAnswerByTaskExamIdsAndUserId(taskExamIds, webContext.getCurrentUser().getId());

        return taskExamList.stream()
                .map(new Function<TaskExam, TaskItemVO>() {
                    @Override
                    public TaskItemVO apply(TaskExam taskExam) {

                        // 给 TaskItemVO 中的 id、title 赋值
                        TaskItemVO taskItemVO = BeanCopyUtils.copyBean(taskExam, TaskItemVO.class);

                        // 给 TaskItemVO 中的 paperItems 赋值
                        TaskExamCustomerAnswer taskExamCustomerAnswer = taskExamCustomerAnswerList.stream()
                                .filter(new Predicate<TaskExamCustomerAnswer>() {
                                    @Override
                                    public boolean test(TaskExamCustomerAnswer taskExamCustomerAnswer) {
                                        return Objects.equals(taskExamCustomerAnswer.getTaskExamId(), taskExam.getId());
                                    }
                                })
                                .findFirst()
                                .orElse(null);
                        // 得到该任务所对应的任务试卷
                        List<TaskItemPaperVO> paperItemVMS = getTaskItemPaperVm(taskExam.getFrameTextContentId(), taskExamCustomerAnswer);
                        taskItemVO.setPaperItems(paperItemVMS);

                        return taskItemVO;
                    }
                })
                .collect(Collectors.toList());

    }

    private List<TaskItemPaperVO> getTaskItemPaperVm(Integer tFrameId, TaskExamCustomerAnswer taskExamCustomerAnswers) {
        TextContent textContent = textContentService.selectById(tFrameId);
        List<TaskItemObject> paperItems = JsonUtil.toJsonListObject(textContent.getContent(), TaskItemObject.class);
        if (ObjectUtils.isEmpty(paperItems)) {
            throw new RuntimeException("任务试卷所对应的文本内容为空");
        }

        List<TaskItemAnswerObject> answerPaperItems = null;
        if (null != taskExamCustomerAnswers) {
            TextContent answerTextContent = textContentService.selectById(taskExamCustomerAnswers.getTextContentId());
            answerPaperItems = JsonUtil.toJsonListObject(answerTextContent.getContent(), TaskItemAnswerObject.class);
        }


        List<TaskItemAnswerObject> finalAnswerPaperItems = answerPaperItems;
        return paperItems.stream().map(paperItem -> {
            TaskItemPaperVO taskItemPaperVO = new TaskItemPaperVO();
            taskItemPaperVO.setExamPaperId(paperItem.getExamPaperId());
            taskItemPaperVO.setExamPaperName(paperItem.getExamPaperName());
                if (null != finalAnswerPaperItems) {
                    finalAnswerPaperItems.stream()
                            .filter(finalAnswerPaperItem -> finalAnswerPaperItem.getExamPaperId().equals(paperItem.getExamPaperId()))
                            .findFirst()
                            .ifPresent(taskItemAnswerObject -> {
                                taskItemPaperVO.setExamPaperAnswerId(taskItemAnswerObject.getExamPaperAnswerId());
                                taskItemPaperVO.setStatus(taskItemAnswerObject.getStatus());
                            });
                }
                return taskItemPaperVO;
            }
        ).collect(Collectors.toList());
    }
}
